#include <iostream>
#include "pedido.h"


Pedido :: Pedido(){
	_numero = 42;
	_atendio = "Cacho";
	_combos.agregar(Combo());
}

Pedido :: Pedido(const int n, const Empleado e, const Lista<Combo> cs){
	_numero = n;
	_atendio = e;
	_combos = cs;
}

int Pedido :: numeroP() const{
	return _numero;
}

Empleado Pedido :: atendioP() const{
	return _atendio;
}

Lista<Combo> Pedido :: combosP() const{
	return _combos;
}

Energia Pedido :: dificultadP() const{
	int cantCombos = _combos.longitud();
	Lista<Combo> copiaL (_combos);
	int i = 0;
	int acum = 0;
	while(i<cantCombos){
		acum = acum + copiaL.cabeza().dificultadC();
		copiaL.cola();
		i++;
	}
	return acum;
}

void Pedido :: agregarComboP(const Combo c){
	_combos.agregarAtras(c);
}

void Pedido :: anularComboP(int i){
	_combos.eliminarPosicion(i);
}

void Pedido :: cambiarBebidaComboP(const Bebida b, int i){

	Lista<Combo> listaNueva;
	Lista<Combo> copiaL (_combos);

	Hamburguesa h = _combos.iesimo(i).sandwichC();
	Energia d = _combos.iesimo(i).dificultadC();
	Combo comboConLaNuevaBebida(b,h,d);

	int n = 0;
	while(n<i){
		listaNueva.agregarAtras(copiaL.iesimo(n));
		n++;
	}

	listaNueva.agregarAtras(comboConLaNuevaBebida);

	n = i;
	while(n>=0){
		copiaL.cola();
		n--;
	}

	listaNueva.concatenar(copiaL);

	_combos = listaNueva;

}

void Pedido :: elMezcladitoP(){

	int i = 0, cantCombos = _combos.longitud();
	Lista<Combo> agregados;

	while(i<cantCombos){
		Combo combito;
		combito = _combos.iesimo(i);
		if(seRepiteC(_combos.iesimo(i),i) || yaEstaAgregado(_combos.iesimo(i), agregados)){
			modificarCombo(combito,agregados,i);
		}
		agregados.agregarAtras(combito);
		i++;
	}
	_combos = agregados;
}

void Pedido :: modificarCombo(Combo& c, Lista<Combo> listaCombos,int i){

	bool encontreCombo = false;
	int j = 0, cantBH = bebidasDelPedido().longitud();

	while(j < cantBH && !encontreCombo){
		Combo nuevoCombo(bebidasDelPedido().iesimo(j),c.sandwichC(),c.dificultadC());
		encontreCombo = !seRepiteC(nuevoCombo,i) && !yaEstaAgregado(nuevoCombo,listaCombos);
		j++;
	}

	Combo nuevoCombo(bebidasDelPedido().iesimo(j-1),c.sandwichC(),c.dificultadC());


	if(!encontreCombo){
		j = 0;
		cantBH = sanguchesDelPedido().longitud();
		while(j < cantBH && !encontreCombo){
			Combo nuevoCombo(c.bebidaC(),sanguchesDelPedido().iesimo(j),c.dificultadC());
			encontreCombo = (!seRepiteC(nuevoCombo,i) && !yaEstaAgregado(nuevoCombo,listaCombos));
			j++;
		}

	Combo nuevoCombo2(c.bebidaC(),sanguchesDelPedido().iesimo(j-1),c.dificultadC());
	nuevoCombo = nuevoCombo2;
	}

	c = nuevoCombo;

}

Lista<Bebida> Pedido :: bebidasDelPedido() const {

	int cantCombos = _combos.longitud();
	int i = 0;

	Lista<Bebida> bebidas;

	bool noSeRepiteBebidaEnCombo = !bebidas.pertenece(_combos.iesimo(i).bebidaC());

	while(i<cantCombos){
		if(noSeRepiteBebidaEnCombo){
			bebidas.agregarAtras(_combos.iesimo(i).bebidaC());
		}
		i++;
	}

	return bebidas;
}

Lista<Hamburguesa> Pedido :: sanguchesDelPedido() const {

	int cantCombos = _combos.longitud();
	int i = 0;

	Lista<Hamburguesa> sanguches;

	bool noSeRepiteSangucheEnCombo = !sanguches.pertenece(_combos.iesimo(i).sandwichC());

	while(i<cantCombos){
		if(noSeRepiteSangucheEnCombo){
			sanguches.agregarAtras(_combos.iesimo(i).sandwichC());
		}
		i++;
	}

	return sanguches;
}

bool Pedido :: seRepiteC(Combo c, int i){

	int cantCombos = _combos.longitud();

	int acum = 0;

	while(i<cantCombos-1){
		if(_combos.iesimo(i+1) == c){
			acum = acum +1;
		}
		i++;
	}

	return acum >= 1;
}


bool Pedido :: yaEstaAgregado(Combo c, Lista<Combo> combos){

	int cantCombos = combos.longitud();
	int i = 0;
	int acum = 0;

	while(i<cantCombos){
		if(combos.iesimo(i) == c){
			acum = acum +1;
		}
		i++;
	}

	return acum == 1;
}

void Pedido :: mostrar(std::ostream& os) const{
		os << "(Num: "<< _numero <<", Atendio: " << _atendio << ", Pedido: " << _combos << ")";
}

void Pedido :: guardar(std::ostream& os) const{
		int i = 0, cantCombos = _combos.longitud();
		os << "P |" << _numero << "| |"<< _atendio << "| [";
		while(i < cantCombos){
				os << "(";
				_combos.iesimo(i).guardar(os);
				os << ")";
		if(i < cantCombos-1){
				os << ",";
				} //Este if es para que no me muestre la ultima coma en la lista. Si no queda [p1,p2,p3,]
		i++;
		}
		os << "]";
}

void Pedido :: cargar(std::istream& is){
	char p;
	Lista<Combo> listaDeCombos;
	is >> p;
	is >> p;
	is >> _numero;
	is >> p;
	is >> p;
	getline(is, _atendio, '|');
	is >> p;
	while(is.peek() == '('){
		is >> p;
		Combo c;
		c.cargar(is);
		listaDeCombos.agregarAtras(c);
		is >> p;
		is >> p;
	}
	_combos = listaDeCombos;
}

std::ostream & operator<<(std::ostream & os,const Pedido & p){
	p.mostrar(os);
	return os;
}

